import { Injectable } from "@nestjs/common";
import { PassportStrategy } from "@nestjs/passport"
import { Request } from "express";
import { Strategy } from "passport-jwt"
import { JwtService } from "@nestjs/jwt"
import { AuthSign } from "./AuthSign";
import { NoSign, PasswordErr } from "src/util/http";
import { cryptoPassword } from "src/util/crypto";
import { UserService } from "src/user/user.service";
import { RoleEnum } from "src/role/role.enum";
import { SystemService } from "src/system/system.service";


@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) {
    private getDefaultToken() {
        return this.jwtService.sign({
            type: "notSign",
        })
    }
    private getHeaderToken(req: Request) {
        const [type, token] = req.headers.authorization?.split(' ') ?? [];
        return type === 'Bearer' ? token : undefined;
    }
    private getCookieToken(req: Request) {
        if (!req.headers.cookie) return this.getDefaultToken();
        const { token } = req.headers.cookie.split(";").reduce((acc, label) => {
            const split = label.split("=");
            acc[split[0].trim()] = split[1];
            return acc;
        }, {} as { token?: string });
        return token
    }
    constructor(
        private readonly jwtService: JwtService,
        private readonly userService: UserService,
        private readonly systemService: SystemService
    ) {
        super({
            jwtFromRequest: (req: Request) => {
                return this.getHeaderToken(req) || this.getCookieToken(req)
            },
            ignoreExpiration: true,
            secretOrKey: "sbppk",
        })
    }

    async validate({
        type,
        id,
        crypto,
        allow,
        system
    }) {
        if (type !== "signed") throw NoSign
        const user = await this.userService.findBy({ id });
        if (!user) throw NoSign
        if (cryptoPassword(user.password) !== crypto) throw PasswordErr
        if (allow != user.login_ip) throw NoSign
        // console.log(system)
        // console.log(system?.name || "无")
        // if (user.role === RoleEnum.boos) {
        //     if (!!system) {
        //         user.system = await this.systemService.system.findOne({ where: { id: system } });
        //     }
        // }
        return user
    }
}
